package main

import (
	"context"
	authpb "coolcar/v1/auth/api/gen/v1"
	"coolcar/v1/auth/auth"
	"coolcar/v1/auth/dao"
	"coolcar/v1/auth/token"
	"coolcar/v1/auth/wechat"
	"coolcar/v1/shared/server"
	"coolcar/v1/shared/zaplog"
	"github.com/dgrijalva/jwt-go"
	"github.com/namsral/flag"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"google.golang.org/grpc"
	"io/ioutil"
	"log"
	"os"
	"time"
)

var (
	mongodbName = "coolcar"
	issuer      = "coolcar/auth"
)

var addr = flag.String("addr", ":8081", "address to listen")
var mongoURI = flag.String("mongo_uri", "mongodb://localhost:27017/?readPreference=primary&ssl=false", "mongo uri")
var privateKeyFile = flag.String("private_key_file", "./auth/token/private_test.key", "private key file")
var wechatAppID = flag.String("wechat_app_id", "<APPID>", "wechat app id")
var wechatAppSecret = flag.String("wechat_app_Secret", "<APPSECRET>", "wechat app secret")

func main() {
	flag.Parse()
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	sugar, err := zaplog.NewZapLogger()
	if err != nil {
		log.Fatalf("failed to create logger: %v", err)
	}
	defer sugar.Sync()

	mc, err := mongo.Connect(ctx, options.Client().ApplyURI(*mongoURI))
	if err != nil {
		sugar.Fatalf("failed to connect mongodb: %v", err)
	}
	db := mc.Database(mongodbName)

	file, err := os.Open(*privateKeyFile)
	if err != nil {
		sugar.Fatalf("failed to open file: %v", err)
	}
	defer file.Close()
	bytes, err := ioutil.ReadAll(file)
	privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(bytes)
	if err != nil {
		sugar.Fatalf("failed to parse private key: %v", err)
	}

	sugar.Fatal(server.RunGRPCServer(&server.Config{
		Name: "auth",
		Addr: *addr,
		RegisterFunc: func(g *grpc.Server) {
			authpb.RegisterAuthServiceServer(g, &auth.Service{
				Sugar:       sugar,
				Mongo:       dao.NewMongo(db),
				TokenExpire: 2 * time.Hour,
				OpenIDResolver: &wechat.Service{
					AppID:     *wechatAppID,
					AppSecret: *wechatAppSecret,
				},
				TokenGenerator: token.NewJWTTokenGenerator(issuer, privateKey),
			})
		},
		Suger: sugar,
	}))
}
